package ds.factcom.model;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Observable;

import javax.swing.table.TableModel;

import ds.factcom.domain.client.Client;
import ds.factcom.domain.invoice.Invoice;
import ds.factcom.domain.payment.Payment;
import ds.factcom.exception.ClientHasNotInvoices;
import ds.factcom.exception.ClientHasNotInvoicesPending;
import ds.factcom.exception.NotExistDomainException;

/**
 * 
 * @author Javier De Luca, Maximiliano Herrera, Matias Samblancat
 *
 */
public class PaymentModel extends Observable{

	private final InvoiceModel invoiceModel;
	private final ClientModel clientModel;
	private Payment payment;
	private Float mount;
	private List<Invoice> invoices;
	private TableModel itemTableModel;
	private PaymentItemTableModel paymentItemTableModel;
	
	public PaymentModel(InvoiceModel invoiceModel, ClientModel clientModel){
		this.invoiceModel = invoiceModel;
		this.clientModel=clientModel;
		this.mount = new Float(0F);
		this.invoices=new ArrayList<Invoice>();
		this.paymentItemTableModel = new PaymentItemTableModel(this);
		this.itemTableModel = paymentItemTableModel;
	}

	public void generatePayment(){
		this.payment = new Payment(this.invoiceModel.getClient(), mount, invoices);
		for (Iterator<Invoice> iterator = this.payment.getInvoices().iterator(); iterator.hasNext();) {
			Invoice invoice = (Invoice) iterator.next();
			invoice.setPayment(this.payment);
		}
		this.payment.getClient().getPayments().add(this.payment);
		this.setChanged();
		this.notifyObservers(Message.PAYMENT_MADE);
	}

	public void findClientByDocument(String documentType, String documentNumber) throws NotExistDomainException, ClientHasNotInvoices, ClientHasNotInvoicesPending {
		this.invoiceModel.findByDocument(documentType, documentNumber);
		this.invoices = this.invoiceModel.findClientWithPendingInvoices(documentType, documentNumber);
		this.paymentItemTableModel.setItems(invoices);
	}

	public Float getMount() {
		this.mount=0F;
		for (Iterator<Invoice> iterator = this.invoices.iterator(); iterator.hasNext();) {
			Invoice invoice = (Invoice) iterator.next();
			if(invoice.getPayment()==null)			
				this.mount += invoice.getMountAbsoluty();
		}
		return this.mount;
	}

	public void findByDocument(String documentType, String documentNumber) throws NotExistDomainException {
	this.clientModel.findByDocument(documentType, documentNumber);
	notifier(Message.CLIENT_FOUND);
	}

	private void notifier(String string) {
		this.setChanged();
		this.notifyObservers(string);
	}
	
	public Client getClient(){
		return clientModel.getClient();		
	}

	public int getNumberOfInvoicesPending() throws NotExistDomainException, ClientHasNotInvoices, ClientHasNotInvoicesPending {
		return clientModel.getNumberOfInvoices(getClient());
	}
	
	public int getPaymentNumber(){
		return this.payment.getId();
	}

	public TableModel getItemTableModel() {
		return itemTableModel;
	}

	public List<Invoice> getInvoices(){
		return invoices;
	}

	public void cleanPayment() {
		this.invoices=new ArrayList<Invoice>();
		paymentItemTableModel.setItems(invoices);
		clientModel.setClient(null);
	}

}